package cn.itcast.wanxinp2p.account.service.impl;

import cn.itcast.wanxinp2p.account.common.AccountErrorCode;
import cn.itcast.wanxinp2p.account.entity.Account;
import cn.itcast.wanxinp2p.account.mapper.AccountMapper;
import cn.itcast.wanxinp2p.account.service.AccountService;
import cn.itcast.wanxinp2p.account.service.SmsService;
import cn.itcast.wanxinp2p.api.account.model.AccountDTO;
import cn.itcast.wanxinp2p.api.account.model.AccountLoginDTO;
import cn.itcast.wanxinp2p.api.account.model.AccountRegisterDTO;
import cn.itcast.wanxinp2p.common.domain.BusinessException;
import cn.itcast.wanxinp2p.common.domain.RestResponse;
import cn.itcast.wanxinp2p.common.domain.StatusCode;
import cn.itcast.wanxinp2p.common.util.PasswordUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hmily.annotation.Hmily;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> implements AccountService {

    @Autowired
    private SmsService smsService;

    @Autowired
    private AccountMapper accountMapper;

    @Value("${sms.enable}")
    private Boolean smsEnable;

    @Override
    public RestResponse getSMSCode(String mobile) {
        // 把短信服务和统一账户服务分开，调用短信服务
        return smsService.getSmsCode(mobile);
    }

    @Override
    public Integer checkMobile(String mobile, String key, String code) {
        //1.校验短信验证码
        smsService.verifySmsCode(key,code);
        //2.校验手机号数据库中有没有，有的话走登录，没有的话走注册
        LambdaQueryWrapper<Account> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Account::getMobile,mobile);
        Integer num = accountMapper.selectCount(queryWrapper);
        return num > 0 ? 1 : 0;
    }

    @Override
    @Hmily(confirmMethod = "confirmRegister", cancelMethod = "cancelRegister")
    public AccountDTO register(AccountRegisterDTO accountRegisterDTO) {
        //把accountRegisterDTO存入account数据库中去
        Account account = new Account();
        account.setUsername(accountRegisterDTO.getUsername());
        account.setMobile(accountRegisterDTO.getMobile());
        account.setPassword(PasswordUtil.generate(accountRegisterDTO.getPassword()));
        if(smsEnable){
            account.setPassword(PasswordUtil.generate(accountRegisterDTO.getMobile()));
        }
        account.setDomain("c");
        account.setStatus(StatusCode.STATUS_OUT.getCode());
        accountMapper.insert(account);
        AccountDTO accountDTO = new AccountDTO();
        BeanUtils.copyProperties(account,accountDTO);
        return accountDTO;
    }

    public void confirmRegister(AccountRegisterDTO registerDTO) {
        log.info("Try没问题，执行Confirm");
    }

    public void cancelRegister(AccountRegisterDTO registerDTO) {
        log.info("Try有问题，执行Cancel");
        //删除账号
        remove(new LambdaQueryWrapper<Account>().eq(Account::getUsername, registerDTO.getUsername()));
    }

    @Override
    public AccountDTO login(AccountLoginDTO accountLoginDTO) {
        //1.先看登陆者是c端用户还是b端用户 c端用户根据手机号查，b端用户根据用户名查
        Account account = null;
        if(accountLoginDTO.getDomain().equalsIgnoreCase("c")){
            account = getAccountByMobile(accountLoginDTO.getMobile());
        }else{
            account = getAccountByUsername(accountLoginDTO.getUsername());
        }
        if(account == null){
            throw new BusinessException(AccountErrorCode.E_130104);
        }
        //2.用户存在，看是否开启验证码登录，没有开启就校验密码登录
        AccountDTO accountDTO = new AccountDTO();
        BeanUtils.copyProperties(account,accountDTO);
        if(smsEnable){ // 如果smsEnable=true，说明是短信验证码登录，不做密码校验,checkMobile已经校验过验证码是否正确，这里直接登录
            return accountDTO;
        }
        if(PasswordUtil.verify(accountLoginDTO.getPassword(),account.getPassword())) {
            throw new BusinessException(AccountErrorCode.E_130105);
        }
        return accountDTO;
    }

    private Account getAccountByMobile(String mobile){
        return accountMapper.selectOne(new LambdaQueryWrapper<Account>().eq(Account::getMobile,mobile));
    }

    private Account getAccountByUsername(String username){
        return accountMapper.selectOne(new LambdaQueryWrapper<Account>().eq(Account::getUsername,username));
    }
}
